#include <cstdio>
#include <cstring>
#include <queue>

const int N = 5005, M = 5505;
int n, m, k, dis[1024][N], sta[N];
int e_cnt, heads[N];
bool vis[1024][N];

std::queue<std::pair<int, int> > q;

struct Edge {
  int v, nxt, s;
} e[M];

inline void add(int u, int v, int s) {
  e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt, e[e_cnt].s = s;
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("testdata.in", "r", stdin);
  freopen("testdata.out", "w", stdout);
#endif
#ifndef LOCAL
  freopen("room.in", "r", stdin);
  freopen("room.out", "w", stdout);
#endif
#endif

  scanf("%d%d%d", &n, &m, &k);
  for (int i = 1, tmp; i <= n; ++i)
    for (int j = 0; j < k; ++j) scanf("%d", &tmp), sta[i] |= (tmp << j);
  for (int i = 1, s, tmp, x, y; i <= m; ++i) {
    scanf("%d%d", &x, &y);
    s = 0;
    for (int j = 0; j < k; ++j) scanf("%d", &tmp), s |= (tmp << j);
    add(x, y, s);
  }
  memset(dis, 0x3f, sizeof(dis));
  dis[sta[1]][1] = 0;
  q.push(std::make_pair(1, sta[1]));
  while (!q.empty()) {
    int u = q.front().first, state = q.front().second;
    q.pop();
    vis[state][u] = false;
    for (int i = heads[u], v; i; i = e[i].nxt) {
      v = e[i].v;
      if (((e[i].s & state) == e[i].s) && dis[state | sta[v]][v] > dis[state][u] + 1) {
        dis[state | sta[v]][v] = dis[state][u] + 1;
        if (!vis[state | sta[v]][v]) q.push(std::make_pair(v, state | sta[v]));
      }
    }
  }
  int ans = 0x3f3f3f3f;
  for (int i = 0; i < 1 << k; ++i) ans = std::min(ans, dis[i][n]);
  if (ans == 0x3f3f3f3f)
    puts("No Solution");
  else
    printf("%d", ans);
  return 0;
}